//处理Fabric.js和Yjs之间的数据同步

import { fabric } from 'fabric';

// 精简序列化方法
const serializeObject = (obj) => {
  // 只序列化必要属性
  const minimalObj = {
    type: obj.type,
    left: obj.left,
    top: obj.top,
    width: obj.width,
    height: obj.height,
    fill: obj.fill,
    stroke: obj.stroke,
    strokeWidth: obj.strokeWidth,
    angle: obj.angle,
    scaleX: obj.scaleX,
    scaleY: obj.scaleY,
    // 根据类型保留特定属性
    ...(obj.type === 'text' && {
      text: obj.text,
      fontSize: obj.fontSize,
      fontFamily: obj.fontFamily
    }),
    ...(obj.type === 'image' && {
      src: obj.src
    })
  };
  return JSON.stringify(minimalObj);
};

// 精简反序列化方法
const deserializeObject = (str) => {
  const obj = JSON.parse(str);
  // 恢复完整对象结构
  return {
    ...obj,
    originX: 'center',
    originY: 'center',
    selectable: true,
    evented: true
  };
};


export const initCanvasSync = (canvas, ycanvas) => {
  // 标记用于避免循环更新
  let isYjsUpdateRef = { value: false };
  
  // 1. 从Yjs获取初始数据并应用到画布
  const initialData = ycanvas.toJSON();
  loadInitialData(canvas, initialData);
  
  // 2. 监听Yjs更新，将远程更改应用到本地画布
  const yObserver = setupYjsObserver(canvas, ycanvas, isYjsUpdateRef);
  
  // 3. 监听Fabric.js事件，将本地更改同步到Yjs
  const fabricUnbind = setupFabricListeners(canvas, ycanvas, isYjsUpdateRef);
  
  // 返回解绑函数
  return {
    unbind: () => {
      ycanvas.unobserve(yObserver);
      fabricUnbind();
    }
  };
};

/**
 * 加载初始数据到画布
 */
const loadInitialData = (canvas, initialData) => {
  // 清空画布
  canvas.clear();
  
  // 添加所有对象
  Object.entries(initialData).forEach(([id, serializedObject]) => {
    try {
      // 解析对象
    const objectData = deserializeObject(serializedObject);
      
      // 创建Fabric对象
      fabric.util.enlivenObjects([objectData], ([fabricObject]) => {
        // 设置ID
        fabricObject.id = id;
        
        // 添加到画布
        canvas.add(fabricObject);
        canvas.requestRenderAll();
      });
    } catch (err) {
      console.error('加载对象失败:', err);
    }
  });
};

/**
 * 设置Yjs观察者处理远程更改
 */
const setupYjsObserver = (canvas, ycanvas, isYjsUpdateRef) => {
  return (event) => {
    // 避免循环更新
    if (isYjsUpdateRef.value) return;
    
    // 标记为Yjs更新
    isYjsUpdateRef.value = true;
    
    try {
      // 处理更改
      event.changes.keys.forEach((change, key) => {
        if (change.action === 'add' || change.action === 'update') {
          // 新增或更新
          const serializedObject = ycanvas.get(key);
          updateObjectOnCanvas(canvas, key, serializedObject);
        } else if (change.action === 'delete') {
          // 删除
          deleteObjectFromCanvas(canvas, key);
        }
      });
      
      // 重新渲染画布
      canvas.requestRenderAll();
    } finally {
      // 清除标记
      isYjsUpdateRef.value = false;
    }
  };
};

/**
 * 更新画布上的对象
 */
const updateObjectOnCanvas = (canvas, id, serializedObject) => {
  try {
    const objectData = deserializeObject(serializedObject);
    
    // 查找是否已存在
    let existingObject = canvas.getObjects().find(obj => obj.id === id);
    
    if (existingObject) {
      // 更新现有对象
      existingObject.set(objectData);
      existingObject.setCoords();
    } else {
      // 创建新对象
      fabric.util.enlivenObjects([objectData], ([fabricObject]) => {
        fabricObject.id = id;
        canvas.add(fabricObject);
      });
    }
  } catch (err) {
    console.error('更新对象失败:', err);
  }
};

/**
 * 从画布删除对象
 */
const deleteObjectFromCanvas = (canvas, id) => {
  const objectToRemove = canvas.getObjects().find(obj => obj.id === id);
  if (objectToRemove) {
    canvas.remove(objectToRemove);
  }
};

/**
 * 设置Fabric.js事件监听器
 */
const setupFabricListeners = (canvas, ycanvas, isYjsUpdateRef) => {
  // 变更缓冲区
  const changesBuffer = new Map();
  let isBatching = false;
  
  // 批量提交变更
  const flushChanges = () => {
    if (changesBuffer.size === 0) return;
    
    ycanvas.doc.transact(() => {
      changesBuffer.forEach((value, key) => {
        if (value === null) {
          ycanvas.delete(key);
        } else {
          ycanvas.set(key, value);
        }
      });
    });
    
    changesBuffer.clear();
    isBatching = false;
  };
  
  // 启动批处理定时器
  const startBatchTimer = () => {
    if (!isBatching) {
      isBatching = true;
      setTimeout(flushChanges, 50); // 50ms批处理窗口
    }
  };
  
  // 对象修改事件
  const handleObjectModified = (e) => {
    if (isYjsUpdateRef.value) return;
    
    const modifiedObject = e.target;
    if (!modifiedObject || !modifiedObject.id) return;
    
    // 序列化对象并缓冲变更 - 使用精简序列化
    const objectData = modifiedObject.toObject(canvas.includeDefaultValues);
    changesBuffer.set(modifiedObject.id, serializeObject(objectData));
    startBatchTimer();
  };
  
  // 对象添加事件
  const handleObjectAdded = (e) => {
    if (isYjsUpdateRef.value) return;
    
    const newObject = e.target;
    if (!newObject) return;
    
    if (!newObject.id) {
      newObject.id = Date.now().toString();
    }
    
    const objectData = newObject.toObject(canvas.includeDefaultValues);
    changesBuffer.set(newObject.id, serializeObject(objectData));
    startBatchTimer();
  };
  
  // 对象删除事件
  const handleObjectRemoved = (e) => {
    if (isYjsUpdateRef.value) return;
    
    const removedObject = e.target;
    if (!removedObject || !removedObject.id) return;
    
    // 标记为删除
    changesBuffer.set(removedObject.id, null);
    startBatchTimer();
  };
  
  // 添加事件监听器
  canvas.on('object:modified', handleObjectModified);
  canvas.on('object:added', handleObjectAdded);
  canvas.on('object:removed', handleObjectRemoved);
  
  // 返回解绑函数
  return () => {
    canvas.off('object:modified', handleObjectModified);
    canvas.off('object:added', handleObjectAdded);
    canvas.off('object:removed', handleObjectRemoved);
  };
};
